﻿using ARchGL.Platform.Utils;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ARchGL.Platform.Electrocar.Application.Utils
{
    /// <summary>
    /// 自定义excel头部标签
    /// </summary>
    [AttributeUsage(AttributeTargets.All)]
    public class ExcelColumn : Attribute
    {
        /// <summary>
        /// 标签名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        public ExcelColumn(string name)
        {
            ColumnName = name;
        }
    }
    public static class EpplusExtensions
    {
        /// <summary>
        /// 获取标签对应excel的Index
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static int GetColumnByName(this ExcelWorksheet ws, string columnName)
        {
            if (ws == null) throw new ArgumentNullException(nameof(ws));
            return ws.Cells["1:1"].FirstOrDefault(c => c.Value.ToString() == columnName).Start.Column;
        }
        /// <summary>
        /// 扩展方法，转换为实体列表
        /// </summary>
        /// <param name="worksheet"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static IEnumerable<T> ConvertSheetToObjects<T>(this ExcelWorksheet worksheet) where T : new()
        {
          
            bool columnOnly(CustomAttributeData y) => y.AttributeType == typeof(ExcelColumn);

            var rows = worksheet.Cells
                .Select(cell => cell.Start.Row)
                .Distinct()
                .OrderBy(x => x);

            var columns = typeof(T)
                .GetProperties()
                .Where(x => x.CustomAttributes.Any(columnOnly))
                .Select(p => new
                {
                    Property = p,
                    Column = p.GetCustomAttributes<ExcelColumn>().First().ColumnName
                }).ToList();

            var str = "";
            var index = worksheet.Cells["1:1"].Last().Start.Column;
            for(int i = 1; i <= index; i++)
            {
                var result = worksheet.Cells[1, i].Value.ToString();
                str += result;
            }

            var collection = rows.Skip(1)
                .Select(row =>
                {
                    var tnew = new T();
                    columns.ForEach(col =>
                    {
                        if( -1 != str.IndexOf(col.Column))
                        {
                            var val = worksheet.Cells[row, GetColumnByName(worksheet, col.Column)];
                            if (val.Value == null)
                            {
                                col.Property.SetValue(tnew, null);
                                return;
                            }
                            col.Property.SetValue(tnew, val.GetValue<string>());
                        } 
                        
                    });

                    return tnew;
                });
            return collection;
        }
    }
}
